﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Xml;
using System.IO;
using TSL_Tools.SqlTools;
using System.Diagnostics;

namespace ReportingEngine
{
    public partial class TSL_ReportingEngine
    {
        public TimeSpan GetAllCoreLoadTestInfo()
        {
            DateTime dt = DateTime.Now;
            listOfRuns.Clear();

            string sqlCmd = Sql_GETCORERUNLIST;

            using (SqlConnection _conn = new SqlConnection(sqlConn))
            {
                _conn.Open();
                SqlCommand _cmd = new SqlCommand(sqlCmd, _conn);
                _cmd.CommandTimeout = cmdTimeout;

                SqlDataReader _rdr = _cmd.ExecuteReader();
                while (_rdr.Read())
                {
                    if (_rdr.GetBoolean(_rdr.GetOrdinal("FLAG_LoadTestParsingFailed")) == false)
                    {
                        LoadTestCoreInfo _info = new LoadTestCoreInfo();
                        _info.resultTypes = 0;

                        _info.runId = _rdr.IsDBNull(_rdr.GetOrdinal("LoadTestRunId")) ? 0 : _rdr.GetInt32(_rdr.GetOrdinal("LoadTestRunId"));
                        _info.LoadTestName = _rdr.IsDBNull(_rdr.GetOrdinal("LoadTestName")) ? "" : _rdr.GetString(_rdr.GetOrdinal("LoadTestName"));
                        _info.description = _rdr.IsDBNull(_rdr.GetOrdinal("Description")) ? "" : _rdr.GetString(_rdr.GetOrdinal("Description"));
                        _info.startTime = _rdr.IsDBNull(_rdr.GetOrdinal("StartTime")) ? DateTime.Now : _rdr.GetDateTime(_rdr.GetOrdinal("StartTime"));
                        _info.duration = _rdr.IsDBNull(_rdr.GetOrdinal("RunDuration")) ? 0 : _rdr.GetInt32(_rdr.GetOrdinal("RunDuration"));
                        _info.runSettingsUsed = _rdr.IsDBNull(_rdr.GetOrdinal("RunSettingUsed")) ? "" : _rdr.GetString(_rdr.GetOrdinal("RunSettingUsed"));
                        _info.controllerName = _rdr.IsDBNull(_rdr.GetOrdinal("ControllerName")) ? "" : _rdr.GetString(_rdr.GetOrdinal("ControllerName"));
                        _info.outcome = _rdr.IsDBNull(_rdr.GetOrdinal("Outcome")) ? "" : _rdr.GetString(_rdr.GetOrdinal("Outcome"));
                        _info.sampleRate = _rdr.IsDBNull(_rdr.GetOrdinal("SampleInterval")) ? 0 : _rdr.GetInt32(_rdr.GetOrdinal("SampleInterval"));

                        _info.resultTypes = _info.resultTypes | (_rdr.GetBoolean(_rdr.GetOrdinal("IsLocalRun")) ? ResultTypesStoredInLoadTest.IsLocalRun : 0x00);
                        _info.resultTypes = _info.resultTypes | (_rdr.GetBoolean(_rdr.GetOrdinal("FLAG_TestAborted")) ? ResultTypesStoredInLoadTest.TestAborted : 0x00);
                        _info.resultTypes = _info.resultTypes | (_rdr.GetBoolean(_rdr.GetOrdinal("FLAG_ContainsDetailedTimingInfo")) ? ResultTypesStoredInLoadTest.ContainsDetailedTimingInfo : 0x00);
                        _info.resultTypes = _info.resultTypes | (_rdr.GetBoolean(_rdr.GetOrdinal("FLAG_ContainsPages")) ? ResultTypesStoredInLoadTest.ContainsPages : 0x00);
                        _info.resultTypes = _info.resultTypes | (_rdr.GetBoolean(_rdr.GetOrdinal("FLAG_ContainsTransactions")) ? ResultTypesStoredInLoadTest.ContainsTransactions : 0x00);
                        _info.resultTypes = _info.resultTypes | (_rdr.GetBoolean(_rdr.GetOrdinal("FLAG_ContainsStepLoadProfile")) ? ResultTypesStoredInLoadTest.ContainsStepLoad : 0x00);

                        // GET THE LoadTestRun file and shove it into an XML document
                        // Then parse that document, adding the data to the _info object
                        MemoryStream ms = new MemoryStream((byte[])_rdr.GetValue(_rdr.GetOrdinal("LoadTest")));
                        xDoc.Load(ms);
                        ParseLoadTestXML(ref _info);

                        // Clean up Analysis notes and set the "ContainsAnalysisNotes" flag if necessary
                        string tempAnalysisNotes = _rdr.IsDBNull(_rdr.GetOrdinal("Comment")) ? "" : _rdr.GetString(_rdr.GetOrdinal("Comment"));
                        if (IgnoreUserNameFromAnalysisNotes)
                            _info.analysisNotes = LoadTestCoreInfo.StripUserNameFromAnalysisNotes(tempAnalysisNotes);
                        else
                            _info.analysisNotes = tempAnalysisNotes;
                        if (_info.analysisNotes.Length > 0)
                            _info.resultTypes = _info.resultTypes | ResultTypesStoredInLoadTest.ContainsAnalysisNotes;

                        // Add Scorecard Data
                        _info.GetScorecardTable(sqlConn, connTimeout, cmdTimeout);
                        
                        // Add list of machines in Perfmon
                        _info.UpdatePerfmonMachinesList(sqlConn, connTimeout, cmdTimeout);

                        // Add the run info to the main list
                        listOfRuns.Add(_info.runId, _info.Clone());
                    }
                } // Keep looping through each run to build the core info                
            }
            // -- Gotten each individual run added. Now add a couple more resultTypes for the transaction and page data, and the list of agents.
            AddListOfAgents();
            return (TimeSpan)(DateTime.Now - dt);
        }

        public DataTable GetSummaryTimingResultsForReportAsTable(int runId)
        {
            return GetSummaryTimingResultsForReportAsTable(runId, false);
        }

        public DataTable NEW_GetSummaryTimingResultsForReportAsTable(int runId)
        {
            string sqlCmd = "SELECT * FROM TSL_View_LoadTestSummary WHERE LoadTestRunId = " + runId.ToString();
            DataTable _table;
            TimeSpan ts = tts.ExecuteReaderTable(sqlCmd, out _table);
            return _table;
        }


        public DataTable GetSummaryTimingResultsForReportAsTable(int runId, bool bUsePerfmon)
        {
            int hasTransactions = listOfRuns[runId].resultTypes.HasFlag(ResultTypesStoredInLoadTest.ContainsTransactions) ? 1 : 0;
            int hasPages = listOfRuns[runId].resultTypes.HasFlag(ResultTypesStoredInLoadTest.ContainsPages) ? 1 : 0;
            string sqlCmd;

            if (!bUsePerfmon &&
                (listOfRuns[runId].resultTypes.HasFlag(ResultTypesStoredInLoadTest.ContainsDetailedTimingInfo) 
                && !listOfRuns[runId].resultTypes.HasFlag(ResultTypesStoredInLoadTest.TestAborted))
                )
            {
                sqlCmd = String.Format(Sql_SUMMARYTIMINGRESULTSFORREPORT, runId, 1, hasTransactions, hasPages);
            }
            else
            {
                sqlCmd = String.Format(Sql_SUMMARYTIMINGRESULTSUSINGPERFMON, runId, 1, 1, 1);
            }

            DataTable _table;
            TimeSpan ts = tts.ExecuteReaderTable(sqlCmd, out _table);

            _table.Columns.Add("TestName", typeof(System.String)).SetOrdinal(1);
            _table.Columns.Add("Description", typeof(System.String)).SetOrdinal(2);
            _table.Columns.Add("StartTime", typeof(System.DateTime)).SetOrdinal(3);
            _table.Columns.Add("Duration", typeof(System.Int32)).SetOrdinal(4);

            _table.Rows[0]["TestName"] = listOfRuns[runId].LoadTestName;
            _table.Rows[0]["Description"] = listOfRuns[runId].description;
            _table.Rows[0]["StartTime"] = listOfRuns[runId].startTime;
            _table.Rows[0]["Duration"] = listOfRuns[runId].duration;

            TimeSpan ts2 = TimeSpan.Zero;
            DateTime dt = DateTime.Now;
            foreach (string machine in listOfRuns[runId].perfmonMachines)
            {
                sqlCmd = String.Format(Sql_AVERAGECPUFORMACHINE, runId, machine);
                object val;
                ts2 += tts.ExecuteScalarSystemObject(sqlCmd, out val);
                _table.Columns.Add(machine + ":CPU", typeof(System.Double));
                _table.Rows[0][machine + ":CPU"] = (val != null ? val : DBNull.Value);
            }
            return _table;
        }

        public Dictionary<string, string> GetSummaryTimingResultsForReport(int runId, bool bUsePerfmon)
        {
            Dictionary<string, string> _dict = new Dictionary<string, string>();
            DataTable _table = GetSummaryTimingResultsForReportAsTable(runId, bUsePerfmon);
            //DataTable _table = NEW_GetSummaryTimingResultsForReportAsTable(runId);

            for (int x = 0; x < _table.Columns.Count; x++)
            {
                _dict.Add(_table.Columns[x].ColumnName, _table.Rows[0][x].ToString());
            }
            return _dict;
        }

        //private TimeSpan AddTransactionAndPageFlagInfoToCoreList()
        //{
        //    DateTime dt = DateTime.Now;

        //    DataTable _table;
        //    tts.ExecuteReaderTable(Sql_GETTRANSANDPAGEMAXQTYCOUNT, out _table);
        //    for (int x = 0; x < _table.Rows.Count; x++)
        //    {
        //        if ((int)_table.Rows[x]["PageCount"] > 0)
        //        {
        //            AddTheResultTypeToTheRunInfo((int)_table.Rows[x]["LoadTestRunId"], ResultTypesStoredInLoadTest.ContainsPages);
        //        }
        //        if ((int)_table.Rows[x]["TransactionCount"] > 0)
        //        {
        //            AddTheResultTypeToTheRunInfo((int)_table.Rows[x]["LoadTestRunId"], ResultTypesStoredInLoadTest.ContainsTransactions);
        //        }
        //    }

        //    return (TimeSpan)(DateTime.Now - dt);
        //}

        private TimeSpan AddListOfAgents()
        {
            DateTime dt = DateTime.Now;

            DataTable _table;
            tts.ExecuteReaderTable(Sql_GETAGENTLIST, out _table);
            for (int x = 0; x < _table.Rows.Count; x++)
            {
                int y = (int)_table.Rows[x][0];
                listOfRuns[y].agents.Add(_table.Rows[x][1].ToString());
            }
            return (TimeSpan)(DateTime.Now - dt);
        }

        //public void AddTheResultTypeToTheRunInfo(int runId, ResultTypesStoredInLoadTest resultType)
        //{
        //    listOfRuns[runId].resultTypes = listOfRuns[runId].resultTypes | resultType;
        //}
    }
}
